home *** CD-ROM | disk | FTP | other *** search
/ EnigmA Amiga Run 1996 February / EnigmA AMIGA RUN 04 (1996)(G.R. Edizioni)(IT)[!][issue 1996-02][Skylink CD III].iso / earcd / comm2 / termsorc.lha / Extras / Source / gtlayout-source.lha / LTP_DetermineSize.c < prev    next >
C/C++ Source or Header  |  1995-09-26  |  26KB  |  965 lines

  1. /*  GadTools layout toolkit
  2. **
  3. **  Copyright © 1993-1995 by Olaf `Olsen' Barthel
  4. **  Freely distributable.
  5. */
  6.  
  7. #include "gtlayout_global.h"
  8.  
  9. VOID __regargs
  10. LTP_DetermineSize(LayoutHandle *Handle,ObjectNode *Node)
  11. {
  12.     if(!Handle -> Failed)
  13.     {
  14.         LONG i,Len,Width,Max;
  15.  
  16.         if(Node -> Label)
  17.         {
  18.             UWORD LabelWidth = LT_LabelWidth(Handle,Node -> Label);
  19.  
  20.             if(Node -> LabelChars * Handle -> GlyphWidth > LabelWidth)
  21.                 LabelWidth = Node -> LabelChars * Handle -> GlyphWidth;
  22.  
  23.             Node -> LabelWidth = LabelWidth;
  24.         }
  25.         else
  26.             Node -> LabelWidth = 0;
  27.  
  28.         switch(Node -> Type)
  29.         {
  30. #ifdef DO_BOOPSI_KIND
  31.             case BOOPSI_KIND:
  32.  
  33.                 if(Node -> Special . BOOPSI . ExactWidth)
  34.                     Node -> Width = Node -> Special . BOOPSI . ExactWidth;
  35.                 else
  36.                     Node -> Width = Node -> Chars * Handle -> GlyphWidth;
  37.  
  38.                 if(Node -> Special . BOOPSI . ExactHeight)
  39.                     Node -> Height = Node -> Special . BOOPSI . ExactHeight;
  40.                 else
  41.                     Node -> Height = Node -> Lines * Handle -> RPort . TxHeight;
  42.  
  43.                 if(Node -> Special . BOOPSI . RelFontHeight)
  44.                     Node -> Height = Handle -> RPort . TxHeight + Node -> Special . BOOPSI . RelFontHeight;
  45.  
  46.                 break;
  47. #endif    /* DO_BOOPSI_KIND */
  48.  
  49. #ifdef DO_LEVEL_KIND
  50.             case LEVEL_KIND:
  51.  
  52.                 Node -> Width    = 6 + Node -> Chars * Handle -> GlyphWidth + 6;
  53.                 Node -> Height    = 2 + Handle -> RPort . TxHeight + 1;
  54.  
  55.                 LTP_GetStorage(Node);
  56.  
  57.                 if(Node -> Special . Level . Level > Node -> Special . Level . Max)
  58.                 {
  59.                     Node -> Special . Level . Level = Node -> Special . Level . Max;
  60.  
  61.                     LTP_PutStorage(Node);
  62.                 }
  63.  
  64.                 if(Node -> Special . Level . Level < Node -> Special . Level . Min)
  65.                 {
  66.                     Node -> Special . Level . Level = Node -> Special . Level . Min;
  67.  
  68.                     LTP_PutStorage(Node);
  69.                 }
  70.  
  71.                 if(!Node -> Special . Level . MaxLevelWidth || Handle -> Rescaled)
  72.                 {
  73.                     LTP_LevelWidth(Handle,Node -> Special . Level . LevelFormat,Node -> Special . Level . DispFunc,Node -> Special . Level . Min,Node -> Special . Level . Max,&Node -> Special . Level . MaxLevelWidth,NULL,Node -> Special . Level . FullLevelCheck);
  74.  
  75.                     Node -> Special . Level . MaxLevelWidth += TextLength(&Handle -> RPort," ",1);
  76.                 }
  77.  
  78.                 Node -> Special . Level . Handle        = Handle;
  79.                 Node -> Special . Level . CustomHook . h_Entry    = (HOOKFUNC)LTP_LevelGadgetDispatcher;
  80.  
  81.                 if(!Node -> Special . Level . Plus)
  82.                     Node -> Special . Level . Plus = Node -> Special . Level . Min;
  83.  
  84.                 if(Node -> LabelChars * Handle -> GlyphWidth > Node -> LabelWidth)
  85.                     Node -> LabelWidth = Node -> LabelChars * Handle -> GlyphWidth;
  86.  
  87.                 if(Node -> LabelWidth > Node -> Width && (Node -> LabelPlace == PLACE_ABOVE || Node -> LabelPlace == PLACE_BELOW))
  88.                     Node -> Width = Node -> LabelWidth;
  89.  
  90.                 if(Node -> Special . Level . LevelPlace == PLACETEXT_LEFT && Node -> LabelPlace == PLACE_LEFT)
  91.                     Node -> LabelWidth += Node -> Special . Level . MaxLevelWidth;
  92.  
  93.                 break;
  94. #endif    /* DO_LEVEL_KIND */
  95.             case GROUP_KIND:
  96.  
  97.                 LTP_LayoutGroup(Handle,Node);
  98.  
  99.                 break;
  100.  
  101.             case XBAR_KIND:
  102.  
  103.                 Node -> Width    = Handle -> GlyphWidth;
  104.                 Node -> Height    = 6;
  105.  
  106.                 break;
  107.  
  108.             case YBAR_KIND:
  109.  
  110.                 Node -> Width    = 6;
  111.                 Node -> Height    = Handle -> RPort . TxHeight;
  112.  
  113.                 break;
  114.  
  115.             case FRAME_KIND:
  116.  
  117.                 if(Node -> Special . Frame . DrawBox)
  118.                 {
  119.                     Node -> Width    = 4 + Node -> Special . Frame . InnerWidth + 4;
  120.                     Node -> Height    = 2 + Node -> Special . Frame . InnerHeight + 2;
  121.                 }
  122.                 else
  123.                 {
  124.                     Node -> Width    = Node -> Special . Frame . InnerWidth;
  125.                     Node -> Height    = Node -> Special . Frame . InnerHeight;
  126.                 }
  127.  
  128.                 break;
  129.  
  130.             case BOX_KIND:
  131.  
  132.                 Node -> LabelWidth = 0;
  133.  
  134.                 if(Node -> Special . Box . Labels)
  135.                 {
  136.                     for(i = 0 ; i < Node -> Lines ; i++)
  137.                     {
  138.                         if((Width = TextLength(&Handle -> RPort,Node -> Special . Box . Labels[i],strlen(Node -> Special . Box . Labels[i]))) > Node -> LabelWidth)
  139.                             Node -> LabelWidth = Width;
  140.                     }
  141.                 }
  142.  
  143.                 if(Node -> LabelChars * Handle -> GlyphWidth > Node -> LabelWidth)
  144.                     Node -> LabelWidth = Node -> LabelChars * Handle -> GlyphWidth;
  145.  
  146.                 Max = Node -> Chars;
  147.  
  148.                 if(Node -> Special . Box . Lines)
  149.                 {
  150.                     LONG MaxWidth = 0;
  151.  
  152.                     for(i = 0 ; i < Node -> Lines ; i++)
  153.                     {
  154.                         if(Node -> Special . Box . Lines[i])
  155.                         {
  156.                             if(Len = strlen(Node -> Special . Box . Lines[i]))
  157.                             {
  158.                                 if((Width = TextLength(&Handle -> RPort,Node -> Special . Box . Lines[i],Len)) > MaxWidth)
  159.                                     MaxWidth = Width;
  160.                             }
  161.                         }
  162.                     }
  163.  
  164.                     if(Max < (MaxWidth + Handle -> GlyphWidth - 1) / Handle -> GlyphWidth)
  165.                         Max = (MaxWidth + Handle -> GlyphWidth - 1) / Handle -> GlyphWidth;
  166.                 }
  167.  
  168.                 Node -> Height    = 2 + Node -> Lines * Handle -> RPort . TxHeight + 2;
  169.                 Node -> Width    = 4 + Max * Handle -> GlyphWidth + 4;
  170.  
  171.                 break;
  172.  
  173.             case BUTTON_KIND:
  174.  
  175.                 if(!Node -> Special . Button . Lines && Node -> Label)
  176.                 {
  177.                     WORD i,Len = strlen(Node -> Label),Count = 0;
  178.  
  179.                     for(i = 0 ; i < Len ; i++)
  180.                     {
  181.                         if(Node -> Label[i] == '\n')
  182.                             Count++;
  183.                     }
  184.  
  185.                     if(Count)
  186.                     {
  187.                         STRPTR *Lines;
  188.  
  189.                         if(Lines = (STRPTR *)LTP_Alloc(Handle,(Count + 2) * sizeof(STRPTR) + Len + 1))
  190.                         {
  191.                             STRPTR String = (STRPTR)(&Lines[Count + 2]);
  192.  
  193.                             strcpy(String,Node -> Label);
  194.  
  195.                             Node -> Special . Button . Lines = Lines;
  196.  
  197.                             do
  198.                             {
  199.                                 *Lines++ = String;
  200.  
  201.                                 for(i = 0 ; String[i] ; i++)
  202.                                 {
  203.                                     if(String[i] == '\n')
  204.                                     {
  205.                                         String[i] = 0;
  206.  
  207.                                         String = &String[i + 1];
  208.  
  209.                                         break;
  210.                                     }
  211.                                 }
  212.                             }
  213.                             while(Count--);
  214.                         }
  215.                         else
  216.                             break;
  217.                     }
  218.                 }
  219.  
  220.                 if(Node -> Special . Button . Lines)
  221.                 {
  222.                     STRPTR    *Index = Node -> Special . Button . Lines;
  223.                     WORD     Count = 0,Width,MaxWidth = 0,Height;
  224.  
  225.                     while(*Index)
  226.                     {
  227.                         Count++;
  228.  
  229.                         if((Width = LT_LabelWidth(Handle,*Index)) > MaxWidth)
  230.                             MaxWidth = Width;
  231.  
  232.                         Index++;
  233.                     }
  234.  
  235.                     Node -> Special . Button . LineCount = Count;
  236.  
  237.                     if(Node -> Chars * Handle -> GlyphWidth > MaxWidth)
  238.                         MaxWidth = Node -> Chars * Handle -> GlyphWidth;
  239.  
  240.                     if(Node -> Lines > Count)
  241.                         Count = Node -> Lines;
  242.  
  243.                     Height = Count * Handle -> RPort . TxHeight;
  244.  
  245.                     if(Node -> Special . Button . ExtraFat)
  246.                     {
  247.                         Node -> Width    = 6 + Handle -> GlyphWidth + MaxWidth + Handle -> GlyphWidth + 6;
  248.                         Node -> Height    = 2 + (2 * Height + Handle -> RPort . TxHeight) / 2 + 2;
  249.                     }
  250.                     else
  251.                     {
  252.                         if(Node -> Special . Button . Smaller)
  253.                         {
  254.                             Node -> Width    = 4 + MaxWidth + 4;
  255.                             Node -> Height    = 2 + Height + 2;
  256.                         }
  257.                         else
  258.                         {
  259.                             Node -> Width    = 6 + MaxWidth + 6;
  260.                             Node -> Height    = 3 + Height + 3;
  261.                         }
  262.                     }
  263.  
  264.                     Node -> Label = "";
  265.                 }
  266.                 else
  267.                 {
  268.                     if(Node -> Chars * Handle -> GlyphWidth > Node -> LabelWidth)
  269.                         Node -> Width = Node -> Chars * Handle -> GlyphWidth;
  270.                     else
  271.                         Node -> Width = Node -> LabelWidth;
  272.  
  273.                     if(Node -> Lines)
  274.                     {
  275.                         if(Node -> Special . Button . ExtraFat)
  276.                         {
  277.                             Node -> Width    = 6 + Handle -> GlyphWidth + Node -> Width + Handle -> GlyphWidth + 6;
  278.                             Node -> Height    = 2 + ((Node -> Lines + 1) * Handle -> RPort . TxHeight) / 2 + 2;
  279.                         }
  280.                         else
  281.                         {
  282.                             if(Node -> Special . Button . Smaller)
  283.                             {
  284.                                 Node -> Width    = 4 + Node -> Width + 4;
  285.                                 Node -> Height    = 2 + (Node -> Lines * Handle -> RPort . TxHeight) + 2;
  286.                             }
  287.                             else
  288.                             {
  289.                                 Node -> Width    = 6 + Node -> Width + 6;
  290.                                 Node -> Height    = 3 + (Node -> Lines * Handle -> RPort . TxHeight) + 3;
  291.                             }
  292.                         }
  293.                     }
  294.                     else
  295.                     {
  296.                         if(Node -> Special . Button . ExtraFat)
  297.                         {
  298.                             Node -> Width    = 6 + Handle -> GlyphWidth + Node -> Width + Handle -> GlyphWidth + 6;
  299.                             Node -> Height    = 2 + (3 * Handle -> RPort . TxHeight) / 2 + 2;
  300.                         }
  301.                         else
  302.                         {
  303.                             if(Node -> Special . Button . Smaller)
  304.                             {
  305.                                 Node -> Width    = 4 + Node -> Width + 4;
  306.                                 Node -> Height    = 2 + Handle -> RPort . TxHeight + 2;
  307.                             }
  308.                             else
  309.                             {
  310.                                 Node -> Width    = 6 + Node -> Width + 6;
  311.                                 Node -> Height    = 3 + Handle -> RPort . TxHeight + 3;
  312.                             }
  313.                         }
  314.                     }
  315.                 }
  316.  
  317.                 Node -> LabelWidth = 0;
  318.                 Node -> LabelPlace = PLACE_IN;
  319.  
  320.                 break;
  321.  
  322.             case CHECKBOX_KIND:
  323.  
  324.                 Node -> Width = Node -> Height = (4 * Handle -> RPort . TxHeight) / 3;
  325.  
  326.                 if(!V39)
  327.                 {
  328.                     if(Node -> Width < CHECKBOX_WIDTH)
  329.                         Node -> Width = CHECKBOX_WIDTH;
  330.  
  331.                     if(Node -> Height < CHECKBOX_HEIGHT)
  332.                         Node -> Height = CHECKBOX_HEIGHT;
  333.                 }
  334.                 else
  335.                 {
  336.                     Node -> Width = (Node -> Width * Handle -> AspectY) / Handle -> AspectX;
  337.  
  338.                     if(Node -> Height < CHECKBOX_HEIGHT)
  339.                     {
  340.                         Node -> Height    = CHECKBOX_HEIGHT;
  341.                         Node -> Width    = (Node -> Height * Handle -> AspectY) / Handle -> AspectX;
  342.                     }
  343.                 }
  344.  
  345.                 break;
  346.  
  347.             case LISTVIEW_KIND:
  348.             {
  349.                 struct TextFont    *Font,*OldFont;
  350.                 WORD         GlyphWidth;
  351.  
  352.                 if(Node -> Special . List . TextAttr)
  353.                 {
  354.                     if(!(Font = LTP_OpenFont(Node -> Special . List . TextAttr)))
  355.                     {
  356.                         Handle -> Failed = TRUE;
  357.  
  358.                         return;
  359.                     }
  360.  
  361.                         // Is this a fixed-width font?
  362.  
  363.                     if(Font -> tf_Flags & FPF_PROPORTIONAL)
  364.                     {
  365.                             // We don't want it
  366.  
  367.                         CloseFont(Font);
  368.  
  369.                         Handle -> Failed = TRUE;
  370.  
  371.                         return;
  372.                     }
  373.  
  374.                     OldFont = Handle -> RPort . Font;
  375.  
  376.                     SetFont(&Handle -> RPort,Font);
  377.  
  378.                     GlyphWidth = Handle -> RPort . TxWidth;
  379.  
  380.                     Node -> Special . List . FixedGlyphWidth    = Handle -> RPort . TxWidth;
  381.                     Node -> Special . List . FixedGlyphHeight    = Handle -> RPort . TxHeight;
  382.                 }
  383.                 else
  384.                 {
  385.                     Font        = NULL;
  386.                     GlyphWidth    = Handle -> GlyphWidth;
  387.                 }
  388.  
  389.                 i    = 0;
  390.                 Max    = 0;
  391.                 Width    = Node -> Chars * GlyphWidth;
  392.  
  393.                 if((ULONG)Node -> Special . List . Labels == 0xFFFFFFFF)
  394.                     Node -> Min = Node -> Max = -1;
  395.                 else
  396.                 {
  397.                     if(Node -> Special . List . Labels)
  398.                     {
  399.                         struct Node *Item;
  400.  
  401.                         SCANLIST(Node -> Special . List . Labels,Item)
  402.                         {
  403.                             i++;
  404.  
  405.                             if((Len = TextLength(&Handle -> RPort,Item -> ln_Name,strlen(Item -> ln_Name))) > Max)
  406.                                 Max = Len;
  407.                         }
  408.                     }
  409.  
  410.                     if(Node -> Special . List . IgnoreListContents)
  411.                         Max = 0;
  412.  
  413.                     Node -> Max = i - 1;
  414.                 }
  415.  
  416.                 if(Max > Width && !Node -> Special . List . SizeLocked)
  417.                 {
  418.                     Width = Max;
  419.  
  420.                     Node -> Chars = (Width + GlyphWidth - 1) / GlyphWidth;
  421.  
  422.                     Width = Node -> Chars * GlyphWidth;
  423.                 }
  424.  
  425.                 if(Node -> Special . List . LockSize)
  426.                     Node -> Special . List . SizeLocked = TRUE;
  427.  
  428.                 if(!V39)
  429.                     Node -> Width = (4 + Width + 4) + (2 + 2 * Handle -> GlyphWidth + 2) + 8;
  430.                 else
  431.                     Node -> Width = (4 + Width + 4) + (2 + 2 * Handle -> GlyphWidth + 2);
  432.  
  433.                 Node -> Height = 2 + Node -> Lines * Handle -> RPort . TxHeight + 2;
  434.  
  435.                 if(Node -> Special . List . ReadOnly)
  436.                 {
  437.                     if(Node -> Special . List . LinkID != -1)
  438.                     {
  439.                         if(!V39)
  440.                             Node -> Height += 2 + Handle -> RPort . TxHeight + 2;
  441.                     }
  442.                 }
  443.                 else
  444.                 {
  445.                     if(Node -> Special . List . LinkID == NIL_LINK)
  446.                     {
  447.                         if(!V39)
  448.                             Node -> Height += 2 + Handle -> RPort . TxHeight + 2;
  449.                     }
  450.                     else
  451.                     {
  452.                         if(Node -> Special . List . LinkID != -1 && Node -> Special . List . LinkID != NIL_LINK)
  453.                             Node -> Height += 3 + Handle -> RPort . TxHeight + 3;
  454.                     }
  455.                 }
  456.  
  457.                     // Switch back to the window font
  458.  
  459.                 if(Font)
  460.                 {
  461.                     SetFont(&Handle -> RPort,OldFont);
  462.  
  463.                     CloseFont(Font);
  464.                 }
  465.  
  466.                 if(Node -> Special . List . ExtraLabels)
  467.                 {
  468.                     for(i = Max = 0 ; Node -> Special . List . ExtraLabels[i] ; i++)
  469.                     {
  470.                         if((Len = TextLength(&Handle -> RPort,Node -> Special . List . ExtraLabels[i],strlen(Node -> Special . List . ExtraLabels[i]))) > Max)
  471.                             Max = Len;
  472.                     }
  473.  
  474.                     Node -> Special . List . ExtraLabelWidth = Max;
  475.                 }
  476.  
  477.                 if(Node -> LabelWidth > Node -> Width && (Node -> LabelPlace == PLACE_ABOVE || Node -> LabelPlace == PLACE_BELOW))
  478.                     Node -> Width = Node -> LabelWidth;
  479.  
  480.                 break;
  481.             }
  482.  
  483.             case MX_KIND:
  484.  
  485.                 i    = 0;
  486.                 Max    = 0;
  487.  
  488.                 while(Node -> Special . Radio . Choices[i])
  489.                 {
  490.                     if((Width = TextLength(&Handle -> RPort,Node -> Special . Radio . Choices[i],strlen(Node -> Special . Radio . Choices[i]))) > Max)
  491.                         Max = Width;
  492.  
  493.                     i++;
  494.                 }
  495.  
  496.                 Node -> Max = i - 1;
  497.  
  498.                 Node -> Special . Radio . LabelWidth = Max;
  499.  
  500.                 if(Node -> LabelChars * Handle -> GlyphWidth > Node -> LabelWidth)
  501.                     Node -> LabelWidth = Node -> LabelChars * Handle -> GlyphWidth;
  502.  
  503.                 Node -> Height = MAX(MX_HEIGHT,Handle -> RPort . TxHeight);
  504.  
  505.                 if(!V39)
  506.                     Node -> Width = MX_WIDTH;
  507.                 else
  508.                 {
  509.                     Node -> Width = (Node -> Height * Handle -> AspectY) / Handle -> AspectX;
  510.  
  511.                     if(Node -> Height < MX_HEIGHT)
  512.                     {
  513.                         Node -> Height = MX_HEIGHT;
  514.                         Node -> Width  = (Node -> Height * Handle -> AspectX) / Handle -> AspectY;
  515.                     }
  516.                 }
  517.  
  518.                 Node -> Lines  = i;
  519.                 Node -> Height = Node -> Lines * (Node -> Height + Handle -> InterHeight) - Handle -> InterHeight;
  520.  
  521.                 break;
  522.  
  523.             case TEXT_KIND:
  524.  
  525.                 if(Node -> Special . Text . Text && !Node -> Special . Text . SizeLocked)
  526.                     Max = TextLength(&Handle -> RPort,Node -> Special . Text . Text,strlen(Node -> Special . Text . Text));
  527.                 else
  528.                     Max = 0;
  529.  
  530.                 Width = Node -> Chars * Handle -> GlyphWidth;
  531.  
  532.                 if(!Node -> Special . Text . SizeLocked && Node -> Special . Text . LockSize)
  533.                 {
  534.                     WORD Chars = (Width + Handle -> GlyphWidth - 1) / Handle -> GlyphWidth;
  535.  
  536.                     if(Chars > Node -> Chars)
  537.                         Node -> Chars = Chars;
  538.  
  539.                     Max = Width = Node -> Chars * Handle -> GlyphWidth;
  540.                 }
  541.  
  542.                 if(Max > Width)
  543.                     Width = Max;
  544.  
  545.                 Node -> Width    = 6 + Width + 6;
  546.                 Node -> Height    = 3 + Handle -> RPort . TxHeight + 3;
  547.  
  548.                 if(Node -> Special . Text . UsePicker)
  549.                     Node -> Width += (4 + (Handle -> GlyphWidth & ~1) + 1 + 4);
  550.  
  551.                 if(Node -> LabelWidth > Node -> Width && (Node -> LabelPlace == PLACE_ABOVE || Node -> LabelPlace == PLACE_BELOW))
  552.                     Node -> Width = Node -> LabelWidth;
  553.  
  554.                 if(Node -> Special . Text . LockSize)
  555.                     Node -> Special . Text . SizeLocked = TRUE;
  556.  
  557.                 break;
  558.  
  559. #ifdef DO_GAUGE_KIND
  560.             case GAUGE_KIND:
  561.  
  562.                 Width = TextLength(&Handle -> RPort,"0%100%",6) + 2 * Handle -> GlyphWidth;
  563.  
  564.                 if(Handle -> GlyphWidth * Node -> Chars > Width)
  565.                     Width = Handle -> GlyphWidth * Node -> Chars;
  566.  
  567.                 Node -> Width = 6 + Width + 6;
  568.  
  569.                 if(Node -> Special . Gauge . NoTicks)
  570.                     Node -> Height = 3 + Handle -> RPort . TxHeight + 3;
  571.                 else
  572.                     Node -> Height = 3 + Handle -> RPort . TxHeight + 2 + Handle -> InterHeight + Handle -> RPort . TxHeight + 3;
  573.  
  574.                 if(Node -> LabelWidth > Node -> Width && (Node -> LabelPlace == PLACE_ABOVE || Node -> LabelPlace == PLACE_BELOW))
  575.                     Node -> Width = Node -> LabelWidth;
  576.  
  577.                 if(Node -> Special . Gauge . Discrete)
  578.                 {
  579.                     Width = ((Node -> Width - 6 - 6) + 9) / 10;
  580.  
  581.                     Node -> Width = 2 + Width * 10 + 2;
  582.                 }
  583.  
  584.                 break;
  585. #endif
  586.  
  587. #ifdef DO_TAPEDECK_KIND
  588.             case TAPEDECK_KIND:
  589.             {
  590.                 LONG Width,Height,OrigWidth,Attempt = 4;
  591.  
  592.                 Width = TextLength(&Handle -> RPort,"AA",2);
  593.  
  594.                 if(Width < 2 * Handle -> GlyphWidth);
  595.                     Width = 2 * Handle -> GlyphWidth;
  596.  
  597.                 if(Width < 2 * Handle -> RPort . TxHeight)
  598.                     Width = 2 * Handle -> RPort . TxHeight;
  599.  
  600.                 if(Node -> Special . TapeDeck . Smaller)
  601.                     Width = (3 * Width) / 4;
  602.  
  603.                 if(Width & 1)
  604.                     Width++;
  605.  
  606.                 OrigWidth = Width;
  607.  
  608.                 do
  609.                 {
  610.                     Width    = 1 + ((((OrigWidth + 5) / 6) * 6) & ~1);
  611.                     Height    = (Handle -> AspectX * Width) / (Handle -> AspectY * 2);
  612.  
  613.                     OrigWidth += 2;
  614.                     Attempt--;
  615.                 }
  616.                 while(Height < 6 && Attempt > 0);
  617.  
  618.                 if(!(Height & 1))
  619.                     Height++;
  620.  
  621.                 if(Node -> Special . TapeDeck . ButtonType == TDBT_BACKWARD || Node -> Special . TapeDeck . ButtonType == TDBT_FORWARD)
  622.                     Node -> Special . TapeDeck . ButtonWidth = Width;
  623.                 else
  624.                     Node -> Special . TapeDeck . ButtonWidth = Width / 2;
  625.  
  626.                 Node -> Special . TapeDeck . ButtonHeight = Height;
  627.  
  628.                 if(Handle -> GlyphWidth * Node -> Chars > Width)
  629.                     Width = Handle -> GlyphWidth * Node -> Chars;
  630.  
  631.                 Node -> Width    = 6 + Width + 6;
  632.                 Node -> Height    = 3 + Height + 3;
  633.  
  634.                 if(Node -> LabelWidth > Node -> Width && (Node -> LabelPlace == PLACE_ABOVE || Node -> LabelPlace == PLACE_BELOW))
  635.                     Node -> Width = Node -> LabelWidth;
  636.  
  637.                 break;
  638.             }
  639. #endif    /* DO_TAPEDECK_KIND */
  640.  
  641.             case NUMBER_KIND:
  642.  
  643.                 Node -> Width    = 6 + Node -> Chars * Handle -> GlyphWidth + 6;
  644.                 Node -> Height    = 2 + Handle -> RPort . TxHeight + 2;
  645.  
  646.                 break;
  647.  
  648.             case CYCLE_KIND:
  649.  
  650.                 Width = Node -> Chars * Handle -> GlyphWidth;
  651.  
  652.                 if(Node -> Special . Cycle . Choices)
  653.                 {
  654.                     for(i = 0 ; Node -> Special . Cycle . Choices[i] ; i++)
  655.                     {
  656.                         if((Len = TextLength(&Handle -> RPort,Node -> Special . Cycle . Choices[i],strlen(Node -> Special . Cycle . Choices[i]))) > Width)
  657.                             Width = Len;
  658.                     }
  659.  
  660.                     Node -> Max = i - 1;
  661.                 }
  662.  
  663.                 Node -> Width    = 26 + Width + 6;
  664.                 Node -> Height    = 3 + Handle -> RPort . TxHeight + 3;
  665.  
  666.                 if(Node -> LabelWidth > Node -> Width && (Node -> LabelPlace == PLACE_ABOVE || Node -> LabelPlace == PLACE_BELOW))
  667.                     Node -> Width = Node -> LabelWidth;
  668.  
  669.                 break;
  670. #if defined(DO_POPUP_KIND) && defined(DO_BOOPSI_KIND)
  671.             case POPUP_KIND:
  672.  
  673.                 Width = Node -> Chars * Handle -> GlyphWidth;
  674.  
  675.                 if(Node -> Special . Popup . Choices)
  676.                 {
  677.                     for(i = 0 ; Node -> Special . Popup . Choices[i] ; i++)
  678.                     {
  679.                         if((Len = TextLength(&Handle -> RPort,Node -> Special . Popup . Choices[i],strlen(Node -> Special . Popup . Choices[i]))) > Width)
  680.                             Width = Len;
  681.                     }
  682.  
  683.                     Node -> Max = i - 1;
  684.                 }
  685.  
  686.                 Node -> Width    = 4 + ((TextLength(&Handle -> RPort,"M",1) & ~1) + 1) + 2 + 4 + 6 + Width + 6;
  687.                 Node -> Height    = 3 + Handle -> RPort . TxHeight + 3;
  688.  
  689.                 if(Node -> LabelWidth > Node -> Width && (Node -> LabelPlace == PLACE_ABOVE || Node -> LabelPlace == PLACE_BELOW))
  690.                     Node -> Width = Node -> LabelWidth;
  691.  
  692.                 break;
  693. #endif
  694.  
  695. #if defined(DO_TAB_KIND) && defined(DO_BOOPSI_KIND)
  696.             case TAB_KIND:
  697.  
  698.                 if(!Node -> Special . Tab . Choices)
  699.                     Handle -> Failed = TRUE;
  700.                 else
  701.                 {
  702.                     struct IBox Box;
  703.  
  704.                     Width = Node -> Chars * Handle -> GlyphWidth;
  705.  
  706.                     for(i = 0 ; Node -> Special . Tab . Choices[i] ; i++);
  707.  
  708.                     Node -> Max = i - 1;
  709.  
  710.                     Node -> Label = NULL;
  711.  
  712.                     if(!LTP_ObtainTabSize(&Box,
  713.                         TIA_Labels,    Node -> Special . Tab . Choices,
  714.                         TIA_DrawInfo,    Handle -> DrawInfo,
  715.                         TIA_Font,    Handle -> TextAttr,
  716.                         TIA_SizeType,    GDOMAIN_MINIMUM,
  717.                     TAG_DONE))
  718.                         Handle -> Failed = TRUE;
  719.                     else
  720.                     {
  721.                         if(Width < Box . Width)
  722.                             Width = Box . Width;
  723.  
  724.                         Node -> Width    = Width;
  725.                         Node -> Height    = Box . Height;
  726.                     }
  727.                 }
  728.  
  729.                 break;
  730. #endif
  731.             case PALETTE_KIND:
  732.  
  733.                 if(Node -> Special . Palette . UsePicker)
  734.                 {
  735.                     Node -> Width = Node -> Height = 3 + Handle -> RPort . TxHeight + 3;
  736.  
  737.                     Node -> Width = (Node -> Width * Handle -> AspectY) / Handle -> AspectX;
  738.  
  739.                     Node -> Special . Palette . IndicatorWidth = Node -> Width;
  740.  
  741.                     Node -> Width += (4 + (Handle -> GlyphWidth & ~1) + 1 + 4);
  742.  
  743.                     if(Node -> LabelWidth > Node -> Width && (Node -> LabelPlace == PLACE_ABOVE || Node -> LabelPlace == PLACE_BELOW))
  744.                         Node -> Width = Node -> LabelWidth;
  745.                 }
  746.                 else
  747.                 {
  748.                     if(Node -> Special . Palette . NumColours)
  749.                         Node -> Max = Node -> Min + Node -> Special . Palette . NumColours - 1;
  750.                     else
  751.                     {
  752.                         if(!Node -> Special . Palette . Depth)
  753.                             Node -> Special . Palette . Depth = 1;
  754.  
  755.                         Node -> Special . Palette . NumColours = 1L << Node -> Special . Palette . Depth;
  756.  
  757.                         Node -> Max = Node -> Min + Node -> Special . Palette . NumColours - 1;
  758.                     }
  759.  
  760.                     if(Node -> Special . Palette . SmallPalette)
  761.                     {
  762.                         Node -> Width    = Handle -> GlyphWidth * (Node -> Max - Node -> Min + 1) + 4;
  763.                         Node -> Height    = 1 + Handle -> RPort . TxHeight + 1;
  764.  
  765.                         if((Node -> Width - 4) / (Node -> Max - Node -> Min + 1) < 8 && Node -> Height < 2 * 8)
  766.                             Node -> Width = 8 * (Node -> Max - Node -> Min + 1) + 4;
  767.  
  768.                         Node -> Width += 2 * Handle -> GlyphWidth;
  769.                     }
  770.                     else
  771.                     {
  772.                         Node -> Width    = 2 * Handle -> GlyphWidth * (Node -> Max - Node -> Min + 1);
  773.                         Node -> Height    = 2 * Handle -> RPort . TxHeight;
  774.                     }
  775.  
  776.                     if(Node -> Width < 20)
  777.                         Node -> Width = 20;
  778.  
  779.                     if(Node -> Chars * Handle -> GlyphWidth > Node -> Width)
  780.                         Node -> Width = Node -> Chars * Handle -> GlyphWidth;
  781.  
  782.                     if(Node -> Special . Palette . NumColours > 16)
  783.                     {
  784.                         Node -> Height    *= 2;
  785.                         Node -> Width    /= 2;
  786.                     }
  787.  
  788.                     if(Node -> Lines)
  789.                     {
  790.                         if(!Node -> Chars)
  791.                             Node -> Width = Handle -> GlyphWidth;
  792.                         else
  793.                             Node -> Width = Node -> Chars * Handle -> GlyphWidth;
  794.  
  795.                         Node -> Height    = Node -> Lines * Handle -> RPort . TxHeight;
  796.                     }
  797.  
  798.                     if(Node -> Special . Palette . ColourTable && !Node -> Special . Palette . TranslateBack)
  799.                     {
  800.                         if(Node -> Special . Palette . TranslateBack = LTP_Alloc(Handle,256))
  801.                         {
  802.                             WORD i;
  803.  
  804.                             for(i = Node -> Min ; i <= Node -> Max ; i++)
  805.                                 Node -> Special . Palette . TranslateBack[Node -> Special . Palette . ColourTable[i]] = i;
  806.                         }
  807.                     }
  808.                 }
  809.  
  810.                 break;
  811.  
  812.             case SCROLLER_KIND:
  813.  
  814.                 if(Node -> Special . Scroller . Vertical)
  815.                 {
  816.                     if(Node -> Special . Scroller . Thin)
  817.                         Node -> Width = 6 + Handle -> GlyphWidth + 6;
  818.                     else
  819.                         Node -> Width = 6 + (3 * Handle -> GlyphWidth) / 2 + 6;
  820.  
  821.                     Node -> Height = 2 + Node -> Lines * Handle -> RPort . TxHeight;
  822.  
  823.                     if(Node -> Special . Scroller . Arrows)
  824.                     {
  825.                         WORD ScrollerHeight = (Handle -> AspectX * Node -> Width) / Handle -> AspectY;
  826.  
  827.                         if(Node -> Height < 2 + Node -> Lines * Handle -> RPort . TxHeight + 2 * ScrollerHeight)
  828.                             Node -> Height = 2 + Node -> Lines * Handle -> RPort . TxHeight + 2 * ScrollerHeight;
  829.  
  830.                         Node -> Special . Scroller . ArrowSize = ScrollerHeight;
  831.                     }
  832.                 }
  833.                 else
  834.                 {
  835.                     Node -> Width  = 6 + Node -> Chars * Handle -> GlyphWidth + 6;
  836.                     Node -> Height = 2 + Handle -> RPort . TxHeight;
  837.  
  838.                     if(Node -> Special . Scroller . Arrows)
  839.                     {
  840.                         WORD ScrollerWidth = (Handle -> AspectY * Node -> Height) / Handle -> AspectX;
  841.  
  842.                         if(Node -> Width < 6 + Handle -> GlyphWidth + 2 * ScrollerWidth + 6)
  843.                             Node -> Width = 6 + Handle -> GlyphWidth + 2 * ScrollerWidth + 6;
  844.  
  845.                         Node -> Special . Scroller . ArrowSize = ScrollerWidth;
  846.                     }
  847.                 }
  848.  
  849.                 if(Node -> LabelWidth > Node -> Width && (Node -> LabelPlace == PLACE_ABOVE || Node -> LabelPlace == PLACE_BELOW))
  850.                     Node -> Width = Node -> LabelWidth;
  851.  
  852.                 break;
  853.  
  854.             case SLIDER_KIND:
  855.             {
  856.                 BOOLEAN CheckIt;
  857.  
  858.                 Node -> Width    = 6 + Node -> Chars * Handle -> GlyphWidth + 6;
  859.                 Node -> Height    = 2 + Handle -> RPort . TxHeight + 1;
  860.  
  861.                 CheckIt = (!Node -> Special . Slider . MaxLevelLen || !Node -> Special . Slider . LevelWidth || Handle -> Rescaled);
  862.  
  863.                 if(Node -> Special . Slider . LevelFormat && CheckIt)
  864.                     LTP_LevelWidth(Handle,Node -> Special . Slider . LevelFormat,Node -> Special . Slider . DispFunc,Node -> Min,Node -> Max,&Node -> Special . Slider . LevelWidth,&Node -> Special . Slider . MaxLevelLen,Node -> Special . Slider . FullLevelCheck);
  865.  
  866.                 if(Node -> Special . Slider . LevelFormat && !V40)
  867.                 {
  868.                     if(Node -> Special . Slider . MaxLevelLen * Handle -> RPort . TxWidth < Node -> Special . Slider . LevelWidth)
  869.                         Node -> Special . Slider . MaxLevelLen = (Node -> Special . Slider . LevelWidth + Handle -> RPort . TxWidth - 1) / Handle -> RPort . TxWidth;
  870.                 }
  871.  
  872.                 if(Node -> Special . Slider . LevelFormat && Node -> Special . Slider . LevelPlace == PLACETEXT_LEFT && Node -> LabelPlace == PLACE_LEFT && Node -> Label && CheckIt)
  873.                 {
  874.                     LONG    space,len;
  875.                     STRPTR    Buffer;
  876.  
  877.                     space = TextLength(&Handle -> RPort," ",1);
  878.                     space = (Node -> Special . Slider . LevelWidth + space - 1) / space;
  879.  
  880.                     if(!V40 && (Handle -> RPort . TxFlags & FPF_PROPORTIONAL))
  881.                     {
  882.                         Node -> Special . Slider . MaxLevelLen++;
  883.  
  884.                         space++;
  885.                     }
  886.  
  887.                     if(Node -> Special . Slider . OriginalLabel)
  888.                         LTP_Free(Handle,Node -> Label,strlen(Node -> Label) + 1);
  889.                     else
  890.                         Node -> Special . Slider . OriginalLabel = Node -> Label;
  891.  
  892.                     len = strlen(Node -> Special . Slider . OriginalLabel);
  893.  
  894.                     if(Buffer = LTP_Alloc(Handle,len + space + 1))
  895.                     {
  896.                         strcpy(Buffer,Node -> Special . Slider . OriginalLabel);
  897.  
  898.                         while(space > 0)
  899.                         {
  900.                             Buffer[len] = ' ';
  901.                             len++;
  902.                             space--;
  903.                         }
  904.  
  905.                         Buffer[len] = 0;
  906.  
  907.                         Node -> Label        = Buffer;
  908.                         Node -> LabelWidth    = LT_LabelWidth(Handle,Node -> Label);
  909.                     }
  910.                     else
  911.                         break;
  912.                 }
  913.  
  914.                 if(Node -> LabelChars * Handle -> GlyphWidth > Node -> LabelWidth)
  915.                     Node -> LabelWidth = Node -> LabelChars * Handle -> GlyphWidth;
  916.  
  917.                 if(Node -> LabelWidth > Node -> Width && (Node -> LabelPlace == PLACE_ABOVE || Node -> LabelPlace == PLACE_BELOW))
  918.                     Node -> Width = Node -> LabelWidth;
  919.  
  920.                 break;
  921.             }
  922.  
  923.             case STRING_KIND:
  924.  
  925.                 Node -> Width    = 6 + Node -> Chars * Handle -> GlyphWidth + 6;
  926.                 Node -> Height    = 3 + Handle -> RPort . TxHeight + 3;
  927.  
  928.                 if(Node -> Special . String . UsePicker)
  929.                     Node -> Width += (4 + (Handle -> GlyphWidth & ~1) + 1 + 4);
  930.  
  931.                 if(Node -> LabelWidth > Node -> Width && (Node -> LabelPlace == PLACE_ABOVE || Node -> LabelPlace == PLACE_BELOW))
  932.                     Node -> Width = Node -> LabelWidth;
  933.  
  934.                 break;
  935.  
  936.             case INTEGER_KIND:
  937.  
  938.                 Node -> Width    = 6 + Node -> Chars * Handle -> GlyphWidth + 6;
  939.                 Node -> Height    = 3 + Handle -> RPort . TxHeight + 3;
  940.  
  941.                 if(Node -> Special . Integer . UseIncrementers)
  942.                 {
  943.                     Node -> Width += 4 + Handle -> GlyphWidth + 4;
  944.                     Node -> Width += 4 + Handle -> GlyphWidth + 4;
  945.                 }
  946.  
  947.                 if(Node -> LabelWidth > Node -> Width && (Node -> LabelPlace == PLACE_ABOVE || Node -> LabelPlace == PLACE_BELOW))
  948.                     Node -> Width = Node -> LabelWidth;
  949.  
  950.                 break;
  951.  
  952.             case PASSWORD_KIND:
  953.             case FRACTION_KIND:
  954.  
  955.                 Node -> Width    = 6 + Node -> Chars * Handle -> GlyphWidth + 6;
  956.                 Node -> Height    = 3 + Handle -> RPort . TxHeight + 3;
  957.  
  958.                 if(Node -> LabelWidth > Node -> Width && (Node -> LabelPlace == PLACE_ABOVE || Node -> LabelPlace == PLACE_BELOW))
  959.                     Node -> Width = Node -> LabelWidth;
  960.  
  961.                 break;
  962.         }
  963.     }
  964. }
  965.